/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package infopanel;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import server.QueueInfo;

/**
 *
 * @author Renato Rosa <2101076@my.ipleiria.pt>
 */
public class Speaker {

    private static Speaker instance;
    private static Process process;
    private static OutputStream speaker;
    private static String speakSynthetizerPath;
    private static String speakSynthetizerArgs;
    private boolean useAlert = true;
    private boolean useVoice = false;
    private static final String GOOGLE_TTS = "http://translate.google.com/translate_tts?tl=pt-pt&q=";
    private Clip alertSound;

    private Speaker() {
        try (InputStream stream = new FileInputStream("infopanel.properties")) {
            if (stream != null) {
                Properties properties = new Properties();
                properties.load(stream);
                useVoice = Boolean.parseBoolean(properties.getProperty("useVoice", "false"));
                speakSynthetizerPath = properties.getProperty("speakSynthetizerPath");
                speakSynthetizerArgs = properties.getProperty("speakSynthetizerArgs");

            }
        } catch (IOException ex) {
            System.err.println("Error: " + ex.getMessage());
        }
    }

    /**
     * Set the value of useAlert
     *
     * @param useAlert new value of useAlert
     */
    public void setUseAlert(boolean useAlert) {
        this.useAlert = useAlert;
    }

    public void setUseVoice(boolean useVoice) {
        this.useVoice = useVoice;
    }

    public static Speaker getSpeaker() {
        if (instance == null) {
            instance = new Speaker();
            try {
                instance.start();
            } catch (IOException ex) {
                Logger.getLogger(Speaker.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        return instance;
    }

    private void start() throws IOException {
        try (InputStream is = getClass().getResourceAsStream("/sound/WindowsNotifySystemGeneric.wav");
                AudioInputStream inputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(is))) {
            alertSound = AudioSystem.getClip();
            alertSound.open(inputStream);
        } catch (LineUnavailableException | UnsupportedAudioFileException ex) {
            System.err.println(ex.getMessage());
        }

        try {
            ProcessBuilder pb = new ProcessBuilder(speakSynthetizerPath, speakSynthetizerArgs);
            process = pb.start();
            speaker = process.getOutputStream();
        } catch (Exception ex) {
            System.err.println(ex.getMessage());
        }
    }

    public void stop() throws IOException {
        if (speaker != null && process != null) {
            speaker.close();
            process.destroy();
        }

        if (alertSound != null) {
            alertSound.close();
        }
    }

    public void advertise(final QueueInfo info) throws IOException {
        StringBuilder sb = new StringBuilder();
        String ticketTextToSay = info.getTicketText().substring(0, 1) + info.getTicketText().substring(1).replaceFirst("^0+", "");
        sb.append("Senha, ").append(ticketTextToSay).append(", posto ").append(info.getWorkStationName());

        if (useAlert) {
            alertSound.stop();
            alertSound.setFramePosition(0);
            alertSound.start();
        }

        if (useVoice) {
            if (speaker != null && process != null) {
                try {
                    speaker.write((sb.toString() + "\n").getBytes());
                    speaker.flush();
                } catch (IOException ex) {
                    System.err.println("Error: " + ex.getMessage());
                }
            }
        }

//        if (useVoice) {
//            String encodedText = URLEncoder.encode(sb.toString(), "UTF-8");
//            URL ttsUrl = new URL(GOOGLE_TTS + encodedText);
//            URLConnection conn = ttsUrl.openConnection();
//            //let's pretend we are a browser :)
//            conn.setRequestProperty("User-Agent", "Mozilla/4.0");
//            conn.connect();
//            
//            //AudioInputStream inputStream = AudioSystem.getAudioInputStream(conn.getInputStream());
//            
//            
//            try (AudioInputStream inputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(conn.getInputStream()))) {
//                SourceDataLine line = AudioSystem.getSourceDataLine(inputStream.getFormat());
//                line.open();
//                line.start();
//            } catch (LineUnavailableException | UnsupportedAudioFileException | IllegalArgumentException e) {
//                System.err.println(e.getMessage());
//            }
//        }

    }
}
